home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
JCSM Shareware Collection 1993 November
/
JCSM Shareware Collection - 1993-11.iso
/
cl720
/
qbnws24j.lzh
/
WINDOWER.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-07-15
|
33KB
|
569 lines
; WINDOWER.ASM This is a window management system, intended to be linked
; with programs written in Microsoft high-level languages.
; It can be used to draw and restore windows in a variety of
; styles and colours. Windows can be zoomed onto the screen
; and may have shadows to the left or right if required.
;
; Author: Christy Gemmell
; For: Assembly-Language ToolBox for QuickBASIC
; Version: 5.00
; Date: 17/6/1991
;
; Compatible with QuickBASIC 4.x, Extended QuickBASIC and BASIC 7
; Assembled with MicroSoft Macro Assembler, MASM version 5.1
;
; Exploding and imploding windows implemented 17/6/91
;
;┌────────────────────────────────────────────────────────────────────────┐
;│ Global symbols and procedures. │
;└────────────────────────────────────────────────────────────────────────┘
;
.model medium
extrn Delay:proc
extrn Explode:proc
extrn ScreenAddress:proc
extrn ScreenCopy:proc
extrn ScreenWrite:proc
extrn VideoType:proc
extrn WriteByte:proc
public PopUp, ShutUp
.code
;┌────────────────────────────────────────────────────────────────────────┐
;│ Data Division. │
;└────────────────────────────────────────────────────────────────────────┘
;
Signature db ' WINDOW MANAGER By Christy Gemmell '
Ulc label word ; Upper left co-ordinate
TlRow db ? ; Top left screen row
TlCol db ? ; Top left screen column
Lrc label word ; Lower right co-ordinate
BrCol db ? ; Right column of window
BrRow db ? ; Bottom row of window
Area label word
Breadth db ? ; Window width (inc shadow)
Height db ? ; Window Height (inc shadow)
ToDo label word
Cols2do db ? ; Columns to restore
Rows2do db ? ; Rows to restore
Rows db ? ; Screen length in rows
Columns db ? ; Screen width in columns
Increment dw ? ; Interval between rows
BuffPtr dw ? ; Pointer to current buffer
BuffTop dw ? ; Offset of first buffer row
BuffEnd dw ? ; Offset of last buffer row
WinTop dw ? ; Offset of first screen row
WinEnd dw ? ; Offset of last screen row
TopLeft label byte
db ' ┌╔╒╓╤╦┬╥' ; TL Corner characters
TopRight label byte
db ' ┐╗╕╖╤╦┬╥' ; TR Corner characters
BotLeft label byte
db ' └╚╘╙╘╚└╙' ; BL Corner characters
BotRight label byte
db ' ┘╝╛╜╛╝┘╜' ; BR Corner characters
Vertical label byte
db ' │║│║│║│║' ; Vertical characters
Horizontal label byte
db ' ─══─══──' ; Horizontal characters
Buffer label byte ; Start of screen buffer
db 4000h dup(0)
BufferTop dw 0 ; End of screen Buffer
;┌────────────────────────────────────────────────────────────────────────┐
;│ POPUP | Save a screen rectangle and replace it with a window. │
;└────────────────────────────────────────────────────────────────────────┘
;
PopUp proc far
push bp ; Save Base pointer
mov bp,sp ; Establish stack frame
push ds ; Preserve segment
push es ; registers and
push di ; index
push si ; pointers
call VideoType ; Get video parameters
push cs ; Align Code and
pop ds ; Data segments
mov Rows,bl ; Store screen height
mov Columns,ah ; Store screen width
mov al,ah ; Transfer number of
xor ah,ah ; columns to AX
shl ax,1 ; and convert
mov Increment,ax ; to bytes
mov al,[bp+20] ; Get top-left row
dec al ; Make it base zero
cmp al,0 ; Check for
jae Pop_01 ; legal
xor al,al ; values
Pop_01:
mov TlRow,al ; Save top-left row
mov al,[bp+18] ; Get top-left column
dec al ; Make it base zero
cmp al,0 ; Check for
ja Pop_02 ; legal
mov al,1 ; values
Pop_02:
mov TlCol,al ; Store top-left column
mov al,[bp+16] ; Get window height
cmp al,2 ; Check for
ja Pop_03 ; legal
mov al,3 ; values
Pop_03:
mov [bp+16],al ; Store window height
mov al,[bp+14] ; Get window width
cmp al,2 ; Check for
ja Pop_04 ; legal
mov al,3 ; values
Pop_04:
mov [bp+14],al ; Store window width
mov al,TlRow ; Get start row
mov ah,[bp+16] ; Get number of rows
add al,ah ; Add 'em together
cmp al,Rows ; Out of bounds?
jb Pop_05 ; No, carry on
jmp Pop_38 ; Else abort
Pop_05:
dec al ; Store bottom
mov BrRow,al ; row number
mov al,TlCol ; Get start column
mov ah,[bp+14] ; Get number of columns
add al,ah ; Add 'em together
cmp al,Columns ; Out of bounds?
jb Pop_06 ; No, carry on
jmp Pop_38 ; Else abort
Pop_06:
dec al ; Store rightmost
mov BrCol,al ; column number
mov al,[bp+10] ; Get required border type
cmp al,0 ; Check
jb Pop_07 ; for
cmp al,8 ; legal
ja Pop_07 ; values
jmp short Pop_08
Pop_07:
mov byte ptr [bp+10],1 ; Set default (single line)
Pop_08:
mov ax,[bp+8] ; See if shadow is required
cmp al,0 ; Check
jb Pop_09 ; for
cmp al,4 ; legal
ja Pop_09 ; values
jmp short Pop_10
Pop_09:
mov byte ptr [bp+8],0 ; Set default (no shadow)
Pop_10:
cmp word ptr [bp+6],0 ; Check for
jge Pop_11 ; legal
mov word ptr [bp+6],20 ; values
Pop_11:
mov ax,1 ; Initialise
push ax ; millisecond
call Delay ; delay routine
xor ax,ax ; Get number of rows
mov al,[bp+16] ; into AX
xor bx,bx ; Get number of columns
mov bl,[bp+14] ; into BX
cmp byte ptr [bp+8],0 ; Shadow required?
jz Pop_12 ; No, skip next bit
inc al ; Add a row
inc bl ; and a column
Pop_12:
mov Height,al ; Store adjusted height
mov Breadth,bl ; Store adjusted width
mul bl ; Find area
shl ax,1 ; in bytes
mov cx,ax ; Transfer to CX
mov si,offset Buffer ; Start of screen stack
Pop_13:
cmp word ptr [si],0 ; Is anything there?
jz Pop_14 ; No, must be free space
mov si,[si] ; Point to next block
jmp Pop_13 ; and try again
Pop_14:
mov ax,si ; Point AX to entry
add ax,6 ; Allow for pointers
add ax,cx ; and area to be saved
mov dx,offset BufferTop ; Point DX to end of stack
cmp ax,dx ; Enough space left?
jb Pop_15 ; Yes, Carry on
jmp Pop_38 ; Otherwise abort
Pop_15:
mov [si],ax ; Set pointer to next block
mov ax,Ulc ; Get row-column co-ordinates
call ScreenAddress ; Convert to memory address
mov WinTop,di ; Save it for later
test byte ptr [bp+8],1 ; Left shadow?
jz Pop_16 ; No, skip next bit
dec di ; One column
dec di ; to the left
Pop_16:
inc si ; Bump buffer
inc si ; pointer
mov [si],di ; Store it in buffer
inc si ; Bump buffer
inc si ; pointer
mov ax,Area ; Get panel Area
mov [si],ax ; Store them in the buffer
inc si ; Bump pointer to
inc si ; screen storage block
xor cx,cx ; Get number of rows
mov cl,ah ; in CX
xchg di,si ; Swap pointers
push ds ; Point DS to
push es ; video segment
pop ds ; and ES to
pop es ; local data
Pop_17:
push cx ; Save row count
push si ; Save screen pointer
mov cl,cs:Breadth ; Set column count
Pop_18:
call ScreenCopy ; Copy word from screen
loop Pop_18 ; For length of row
pop si ; Bump pointer
add si,cs:Increment ; to next row
pop cx ; Recover row count
loop Pop_17 ; For each row
push es ; Realign Code and
pop ds ; Data segments
xor ah,ah ; Get all parameters in AX
mov al,TlRow ; Get upper-left row
inc al ; Must use BASIC numbering
push ax ; Pass the argument
mov al,TlCol ; Get upper-left column
inc al ; Must use BASIC numbering
push ax ; Pass the argument
mov al,BrRow ; Get lower-right row
inc al ; Must use BASIC numbering
push ax ; Pass the argument
mov al,BrCol ; Get lower-right column
inc al ; Must use BASIC numbering
push ax ; Pass the argument
push [bp+12] ; Pass display attribute
push [bp+6] ; Pass speed value
call Explode ; Display the window
mov ax,Ulc ; Get row/column co-ordinate
call ScreenAddress ; Convert to memory address
cmp byte ptr [bp+10],0 ; Border required?
ja Pop_19 ; Yes, draw it
jmp Pop_23 ; Else check for shadow
Pop_19:
xor bx,bx ; Border type
mov bl,[bp+10] ; to BX
mov ah,[bp+12] ; Attribute to AH
push di ; Save screen offset
mov al,TopLeft[bx] ; Border character to AL
call ScreenWrite ; Send it to the screen
mov al,Horizontal[bx] ; Border character to AL
xor cx,cx ; Window width
mov cl,[bp+14] ; to CX
dec cl ; Subtract
dec cl ; corners
Pop_20:
call ScreenWrite ; Send it to the screen
loop Pop_20
mov al,TopRight[bx] ; Border character to AL
call ScreenWrite ; Send it to the screen
pop di ; Recover offset
add di,Increment ; Bump to next row
mov al,Vertical[bx] ; Border character to AL
mov cl,[bp+16] ; Window height to CX
dec cl ; Subtract top and
dec cl ; bottom rows
Pop_21:
push cx ; Save counter
push di ; Save screen pointer
call ScreenWrite ; Left border
mov cl,[bp+14] ; Get window width
dec cl ; Point
dec cl ; to
shl cx,1 ; rightmost
add di,cx ; column
call ScreenWrite ; Right border
pop di ; Recover screen pointer
add di,Increment ; Bump to next row
pop cx ; Recover row count
loop Pop_21 ; For each row
mov al,BotLeft[bx] ; Border character to AL
call ScreenWrite ; Send it to the screen
mov al,Horizontal[bx] ; Border character to AL
mov cl,[bp+14] ; Get window width
dec cl ; Subtract
dec cl ; corners
Pop_22:
call ScreenWrite ; Send it to the screen
loop Pop_22
mov al,BotRight[bx] ; Border character to AL
call ScreenWrite ; Send it to the screen
Pop_23:
cmp byte ptr [bp+8],0 ; Shadow required?
ja Pop_24 ; Yes, handle it
jmp Pop_37 ; Else wrap everything up
Pop_24:
mov di,WinTop ; Back to top-left corner
add di,Increment ; start at next row down
xor cx,cx ; Get window width
mov cl,[bp+14] ; into CX
shl cx,1 ; Include attribute bytes
cmp byte ptr [bp+8],2 ; Solid shadow?
ja Pop_30 ; No, make it transparant
cmp byte ptr [bp+8],1 ; Left shadow?
jne Pop_25 ; No, must be right
dec di ; Left one
dec di ; column
jmp short Pop_26 ; Get to work
Pop_25:
add di,cx ; Offset past right-hand edge
Pop_26:
mov ax,720h ; Space on black background
push cx ; Save width for now
mov cl,[bp+16] ; Rows to shadow
Pop_27:
call ScreenWrite ; Send it to the screen
add di,Increment ; Bump to
dec di ; next
dec di ; row
loop Pop_27 ; For height of window
pop cx ; Recover window width
sub di,Increment ; Back up one row
cmp byte ptr [bp+8],1 ; Left shadow?
je Pop_28 ; No, must be right
sub di,cx ; Jump back to start of row
inc di ; Begin one column
inc di ; in from left
Pop_28:
shr cx,1 ; Convert width to columns
Pop_29:
call ScreenWrite ; Put black shadow
loop Pop_29 ; under the bottom row
jmp short Pop_37 ; Branch to the exit
Pop_30:
cmp byte ptr [bp+8],3 ; Left shadow?
jne Pop_31 ; No, must be right
dec di ; Left one
dec di ; column
jmp short Pop_32 ; Get to work
Pop_31:
add di,cx ; Offset past right-hand edge
Pop_32:
inc di ; Bump to attribute byte
mov al,8 ; Dark grey background
push cx ; Save width for now
mov cl,[bp+16] ; Rows to shadow
Pop_33:
call WriteByte ; Set display attribute
add di,Increment ; Bump to
dec di ; next row
loop Pop_33 ; For height of window
pop cx ; Recover window width
sub di,Increment ; Back up
inc di ; one row
cmp byte ptr [bp+8],3 ; Left shadow?
jne Pop_34 ; No, must be right
dec di ; Back up one column
jmp short Pop_35 ; Start on bottom row
Pop_34:
sub di,cx ; Jump back to the
inc di ; beginning of the row
Pop_35:
shr cx,1 ; Convert width to columns
Pop_36:
call WriteByte ; Set display attribute
inc di ; Bump past character byte
loop Pop_36 ; For width of window
Pop_37:
xor ax,ax ; Report no error
Pop_38:
pop si ; Clean up the stack
pop di
pop es
pop ds
pop bp
ret 16 ; Return to caller
PopUp endp
;┌────────────────────────────────────────────────────────────────────────┐
;│ Close the last window opened by restoring the screen under it. │
;└────────────────────────────────────────────────────────────────────────┘
;
; If a delay is specified, this routine produces the effect of imploding
; the storage buffer contents onto the screen, making the window appear
; to vanish into a point source.
;
ShutUp proc far
push bp ; Save base pointer
mov bp,sp ; Establish stack frame
push ds ; Save segment
push es ; registers and
push di ; index
push si ; pointers
push cs ; Align code and
pop ds ; data segments
cld ; Clear direction forward
call VideoType ; Get video parameters
mov al,ah ; Transfer number of
xor ah,ah ; columns to AX
shl ax,1 ; and convert
mov Increment,ax ; to bytes
mov si,offset Buffer ; DS:SI==> screen buffer
xor ax,ax ; Initialise
push ax ; back pointer
Shut_01:
cmp word ptr [si],0 ; Is anything there?
jz Shut_02 ; No, we're at the end
pop ax ; Retrieve pointer
push si ; Save present pointer
mov si,[si] ; Point to next block
jmp Shut_01 ; Keep searching
Shut_02:
pop si ; Retrieve last pointer
cmp si,0 ; Was there anything?
jnz Shut_03 ; Yes, proceed
mov ax,1 ; Else set Errorlevel
jmp Shut_14 ; and abort
Shut_03:
mov BuffPtr,si ; Save buffer pointer
inc si ; Bump to
inc si ; next entry
mov di,[si] ; ES:DI==> screen location
mov WinTop,di ; Save screen offset
inc si ; Bump to
inc si ; next entry
mov ax,[si] ; Get panel dimensions
mov Area,ax ; Store them
mov ToDo,ax ; for later
inc si ; Bump to screen
inc si ; storage block
mov BuffTop,si ; Save buffer pointer
xor bx,bx ; AX has window width
xchg bl,ah ; BX has window height
dec bl ; less one row
shl bx,1 ; Convert to bytes
mul bx ; Calculate offset
add ax,si ; of the last row
mov BuffEnd,ax ; Save this as well
mov ax,Increment ; Multiply screen width
mov bl,Height ; by window height
dec bl ; less one row
mul bx ; Result is relative offset
add ax,di ; Now convert it to the
mov WinEnd,ax ; absolute screen offset
xor ax,ax ; Get video segment
call ScreenAddress ; and CRT status port
cmp word ptr [bp+6],0 ; Check for
jge Shut_04 ; legal delay
mov word ptr [bp+6],20 ; values
Shut_04:
xor cx,cx ; Clear counter
mov si,BuffTop ; DS:SI==> first buffer row
mov di,WinTop ; ES:DI==> first screen row
mov cl,Cols2do ; Number of words to copy
Shut_05:
call ScreenCopy ; Send word to the screen
loop Shut_05 ; For length of row
dec Rows2do ; All rows done?
jnz Shut_06 ; No, carry on
jmp Shut_13 ; Otherwise depart
Shut_06:
mov si,BuffEnd ; DS:SI==> last buffer row
mov di,WinEnd ; ES:DI==> last screen row
mov cl,Cols2do ; Number of words to copy
Shut_07:
call ScreenCopy ; Send word to the screen
loop Shut_07 ; For length of row
dec Rows2do ; All rows done?
jnz Shut_08 ; No, carry on
jmp Shut_13 ; Otherwise depart
Shut_08:
xor ax,ax ; Clear AX
mov si,BuffTop ; Reset
mov al,Breadth ; pointer
shl al,1 ; to first
add si,ax ; buffer
mov BuffTop,si ; row
mov di,WinTop ; Do the same
add di,Increment ; for the first
mov WinTop,di ; screen row
mov ax,BuffEnd ; Reset
mov cl,Breadth ; pointer
shl cl,1 ; to last
sub ax,cx ; buffer
mov BuffEnd,ax ; row
mov ax,WinEnd ; Do the same
sub ax,Increment ; for the last
mov WinEnd,ax ; screen row
Shut_09:
cmp si,BuffEnd ; End of buffer?
ja Shut_10 ; Yes, see if we've finished
call ScreenCopy ; Send word to the screen
xor ax,ax ; Clear AX again
mov al,Breadth ; Keep
dec al ; doing
shl al,1 ; it
add si,ax ; all
add di,Increment ; down
dec di ; the
dec di ; left
jmp short Shut_09 ; side
Shut_10:
dec Cols2do ; All columns done?
jz Shut_13 ; If so, depart
mov al,Cols2do ; How far to the
shl al,1 ; end of the row?
mov si,BuffTop ; Point SI to
add si,ax ; buffer data
mov di,WinTop ; Point DI to
add di,ax ; screen offset
Shut_11:
call ScreenCopy ; Send word to the screen
cmp si,BuffEnd ; End of buffer?
ja Shut_12 ; Yes, see if we're finished
xor ax,ax ; Clear AX again
mov al,Breadth ; Keep
dec al ; doing
shl al,1 ; it
add si,ax ; all
add di,Increment ; down
dec di ; the
dec di ; right
jmp short Shut_11 ; side
Shut_12:
dec Cols2do ; All columns done?
jz Shut_13 ; If so, depart
add BuffTop,2 ; Each subsequent
add BuffEnd,2 ; row starts
add WinTop,2 ; another word
add WinEnd,2 ; further in
push [bp+6] ; Pass speed value
call Delay ; Pause awhile
jmp Shut_04 ; Then do it all again
Shut_13:
mov di,BuffPtr ; Recover buffer pointer
mov cx,[di] ; Pointer to next block
sub cx,di ; Calculate length of block
inc cx
push ds ; Point ES to Data Segment
pop es
xor ax,ax ; Clear AX
rep stosb ; Zero restored block
Shut_14:
pop si ; Clean up the stack
pop di
pop es
pop ds
pop bp
ret 2 ; Return to caller
ShutUp endp
end
;┌────────────────────────────────────────────────────────────────────────┐
;│ (c) 1988,1991 By Christy Gemmell and Singular SoftWare. │
;└────────────────────────────────────────────────────────────────────────┘